package com.lin.exception;

import com.baomidou.mybatisplus.extension.api.R;
import com.lin.constant.ResultCode;
import com.lin.utils.Result;
import com.qiniu.common.QiniuException;
import io.jsonwebtoken.MalformedJwtException;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationException;
import org.elasticsearch.action.search.SearchPhaseExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.sql.SQLIntegrityConstraintViolationException;

/**
 * @program: blog
 * @description: 全局异常
 * @author: Lin
 * @create: 2020-04-03 12:28
 **/
@ResponseBody
@ControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);



    /**
     * 校验异常
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result exceptionHandler(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        String errorMesssage = "";
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            errorMesssage += fieldError.getDefaultMessage() + "!";
        }
        return Result.failure(ResultCode.Valid_Exception,errorMesssage);
    }

    /**
     * 校验异常
     */
    @ExceptionHandler(value = BindException.class)
    public Result validationExceptionHandler(BindException e) {
        BindingResult bindingResult = e.getBindingResult();
        String errorMesssage = "";
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            errorMesssage += fieldError.getDefaultMessage() + "!";
        }
        return Result.failure(ResultCode.BIND_Exception,errorMesssage);
    }



    /**
     * 处理Shiro权限拦截异常
     * 如果返回JSON数据格式请加上 @ResponseBody注解
     * @Author Sans
     * @CreateTime 2019/6/15 13:35
     * @Return Map<Object> 返回结果集
     */

    @ExceptionHandler(value = AuthorizationException.class)
    public Result authorizationHandler(){
        return Result.failure(ResultCode.Authorization_Exception);
    }

    /**
     * 处理Shiro认证异常
     * 如果返回JSON数据格式请加上 @ResponseBody注解
     * @Author Sans
     * @CreateTime 2019/6/15 13:35
     * @Return Map<Object> 返回结果集
     */

    @ExceptionHandler(value = AuthenticationException.class)
    public Result authenticationExceptionHandler(){
        return Result.failure(ResultCode.Authentication_Exception);
    }


    /**
     * 处理Shiro密码不正确
     * @return
     */
    @ExceptionHandler(value = IncorrectCredentialsException.class)
    public Result incorrectCredentialsHandler(){
        return Result.failure(ResultCode.IncorrectCredentials_Exception);
    }

    /**
     * 处理Shiro账号不正确
     * @return
     */
    @ExceptionHandler(value = UnknownAccountException.class)
    public Result unknownAccountHandler(){
        return Result.failure(ResultCode.UnknownAccount_Exception);
    }


    /**
     * sql完整性约束违反异常
     * @return
     */
    @ExceptionHandler(value = DuplicateKeyException.class)
    public Result duplicateKeyHandler(){
        return Result.failure(ResultCode.DuplicateKey_Exception);
    }

    /**
     * HTTP方法不支持异常
     * @return
     */
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    public Result httpRequestMethodNotSupportedHandler(){
        return Result.failure(ResultCode.Http_Request_Method_NotSupported_Exception);
    }

    /**
     * ElasticSearch搜索执行阶段异常
     * @return
     */
    @ExceptionHandler(value = SearchPhaseExecutionException.class)
    public Result searchPhaseExecutionHandler(SearchPhaseExecutionException e){
        return Result.failure(ResultCode.Search_Phase_Execution_Exception,e.toString());
    }

    /**
     * MQ客户端异常
     */
    @ExceptionHandler(MQClientException.class)
    public Result mqClientException(MQClientException e) {
        return  Result.failure(ResultCode.MQClient_Exception,e.toString());
    }

    /**
     * 消息服务器异常
     */
    @ExceptionHandler(MQBrokerException.class)
    public Result mqBrokerException(MQBrokerException e) {
        return  Result.failure(ResultCode.MQBroker_Exception,e.toString());
    }

    /**
     * 文件服务器异常
     */
    @ExceptionHandler(QiniuException.class)
    public Result qiNiuException(MQBrokerException e) {
        return  Result.failure(ResultCode.QINIU_Exception,e.toString());
    }


    /**
     * JWT Token 解析异常
     * @param e
     * @return
     */
    @ExceptionHandler(MalformedJwtException.class)
    public Result malformedJwtException(MQBrokerException e) {
        return  Result.failure(ResultCode.MAL_Formed_JwtException,e.toString());
    }

    /**
     * 拦截未知的运行时异常
     */
    @ExceptionHandler(RuntimeException.class)
    public Result notFount(RuntimeException e) {
        log.error("运行时异常:", e);
        return  Result.failure(ResultCode.RUNTIME_Exception,e.toString());
    }


    /**
     * 系统异常
     */
    @ExceptionHandler(Exception.class)
    public Result handleException(Exception e) {
        log.error(e.getMessage(), e);
        return  Result.failure(ResultCode.SYSTEM_Exception,e.toString());
    }


}
